package com.ccp.dev.form.controller;

import com.ccp.dev.core.basic.annotion.Action;
import com.ccp.dev.core.basic.consts.UrlConstants;
import com.ccp.dev.core.basic.db.datasource.DbContextHolder;
import com.ccp.dev.core.basic.internationalization.SysBaseController;
import com.ccp.dev.core.basic.model.SysAuditModelType;
import com.ccp.dev.core.basic.response.ResultData;
import com.ccp.dev.core.basic.table.BaseTableMeta;
import com.ccp.dev.core.basic.table.IDbView;
import com.ccp.dev.core.basic.table.TableModel;
import com.ccp.dev.core.basic.util.UUIDUtils;
import com.ccp.dev.core.basic.web.query.QueryFilter;
import com.ccp.dev.core.util.RequestUtil;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.core.util.log.SysAuditThreadLocalHolder;
import com.ccp.dev.form.consts.FormConstants;
import com.ccp.dev.form.model.FormDialog;
import com.ccp.dev.form.model.FormQuery;
import com.ccp.dev.form.service.FormDialogService;
import com.ccp.dev.form.service.FormQueryService;
import com.ccp.dev.form.table.TableMetaFactory;
import com.ccp.dev.form.util.QueryResult;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义查询控制器类
 *
 * @author chenjing
 */
@Controller
@RequestMapping(UrlConstants.PROJECT_ROOT + UrlConstants.PROJECT_MODULE_FORM + "/formQuery")
@Action(ownermodel = SysAuditModelType.FORM_MANAGEMENT)
public class FormQueryController extends SysBaseController {

    @Resource
    private FormQueryService formQueryService;

    @Resource
    private FormDialogService formDialogService;

    @Value("${mybatis.configuration.database-id}")
    private String dataSourceType;

    /**
     * 数据列表页面跳转
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/list")
    @Action(description = "自定义查询列表页面跳转",exectype = "页面跳转日志")
    public String formQueryViewList() {
        return getAutoView();
    }

    /**
     * 新增页面跳转
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/add")
    @Action(description = "自定义查询新增页面跳转",exectype = "页面跳转日志")
    public String formQueryViewAdd(HttpServletRequest request, ModelMap modelMap) {
        String formQueryId = RequestUtil.getString(request, "formQueryId");
        String alias = RequestUtil.getString(request, "alias");
        modelMap.put("formQueryId", formQueryId);
        modelMap.put("alias", alias);
        return getAutoView();
    }

    /**
     * 设置列页面跳转
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/setCol")
    @Action(description = "自定义查询设置列页面跳转",exectype = "页面跳转日志")
    public String formQueryViewSetCol(HttpServletRequest request, ModelMap modelMap) {
        String formQueryId = RequestUtil.getString(request, "formQueryId");
        String dsName = RequestUtil.getString(request, "dsName");
        int isTable = RequestUtil.getInt(request, "isTable");
        String objectName = RequestUtil.getString(request, "objectName");
        modelMap.put("formQueryId", formQueryId);
        modelMap.put("dsName", dsName);
        modelMap.put("isTable", isTable);
        modelMap.put("objectName", objectName);
        return getAutoView();
    }

    /**
     * 预览页面跳转
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/preview")
    @Action(description = "自定义查询预览页面跳转",exectype = "页面跳转日志")
    public String formQueryViewPreview(HttpServletRequest request, ModelMap modelMap) {
        String alias = RequestUtil.getString(request, "alias");
        modelMap.put("alias", alias);
        return getAutoView();
    }

    /**
     * 取得自定义查询的分页列表
     *
     * @param request HttpServletRequest
     * @return ResultData
     */
    @RequestMapping(UrlConstants.MODULE_FUNCTION_LIST)
    @ResponseBody
    @Action(description = "查询自定义查询分页列表", exectype = "查询日志",
            detail = "查询自定义查询分页列表<#if success>成功<#else>失败</#if>")
    public ResultData list(HttpServletRequest request) {
        QueryFilter filter = new QueryFilter(request, true);
        try {
            List<FormQuery> formQueryList = formQueryService.queryList(filter);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("query.success", filter.getPageBean().getTotalCount(), formQueryList);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
    }

    /**
     * 删除自定义查询
     *
     * @param request HttpServletRequest
     * @return ResultData
     */
    @RequestMapping("/del")
    @ResponseBody
    @Action(description = "删除自定义查询", exectype = "删除日志", detail = "删除自定义查询<#if success>成功<#else>失败</#if>")
    public ResultData del(HttpServletRequest request) {
        try {
            String[] lAryId = RequestUtil.getStringAryByStr(request, "ids");
            formQueryService.delByIds(lAryId);
            SysAuditThreadLocalHolder.putParamerter("success", true);
        } catch (Exception ex) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("delete.failure");
        }
        return getResultDataSuccess("delete.success");
    }

    /**
     * 根据数据源，输入的对象类型，对象名称获取对象列表。
     * <pre>
     *  1.对象类型为表。
     *  	返回表的map对象。
     *  2.对象为视图
     *  	返回视图列表对象。
     * </pre>
     *
     * @param request HttpServletRequest
     * @return ResultData
     */
    @RequestMapping("/getByDsObjectName")
    @ResponseBody
    @Action(description = "查看表名或视图名列表", exectype = "查询日志",
            detail = "查看表名或视图名列表<#if success>成功<#else>失败</#if>")
    public ResultData getByDsObjectName(HttpServletRequest request) {
        String dsName = RequestUtil.getString(request, "dsName");
        String objectName = RequestUtil.getString(request, "objectName");
        int isTable = RequestUtil.getInt(request, "isTable");
        Map map = new HashMap(16);
        try {
            String dbType = dataSourceType.toLowerCase();
            if (isTable == FormConstants.DEFAULT_INT_ONE) {
                BaseTableMeta meta = TableMetaFactory.getMetaData(dsName, dbType);
                Map<String, String> tableMap = meta.getTablesByName(objectName);
                map.put("tables", tableMap);
            } else {
                IDbView dbView = TableMetaFactory.getDbView(dsName, dbType);
                List<String> views = dbView.getViews(objectName);
                map.put("views", views);
            }
            DbContextHolder.clearDataSource();
            DbContextHolder.setDefaultDataSourceMy(dataSourceType);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("query.success", map);
        } catch (Exception ex) {
            ex.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("formTable.getExtTable.error");
        }
    }

    /**
     * 设置列页面获取数据
     *
     * @return ResultData
     */
    @RequestMapping("/setCol")
    @ResponseBody
    @Action(description = "根据表名或视图名查看字段名和字段类型列表", exectype = "查询日志",
            detail = "查看字段名和字段类型列表<#if success>成功<#else>失败</#if>")
    public ResultData formQuerySetCol(HttpServletRequest request) {
        Map map = new HashMap(16);
        String id = RequestUtil.getString(request, "formQueryId");
        int type = RequestUtil.getInt(request, "type");
        String dsName;
        String objectName;
        int isTable;
        if (StringUtil.isEmpty(id)) {
            dsName = RequestUtil.getString(request, "dsName");
            isTable = RequestUtil.getInt(request, "isTable");
            objectName = RequestUtil.getString(request, "objectName");
        } else {
            //自定义查询
            if (type == FormConstants.FORM_QUERY) {
                FormQuery bpmFormQuery = formQueryService.getOneById(id);
                isTable = bpmFormQuery.getIsTable();
                dsName = bpmFormQuery.getDsalias();
                objectName = bpmFormQuery.getObjName();
                map.put("bpmFormQuery", bpmFormQuery);
                //自定义对话框
            } else {
                FormDialog formDialog = formDialogService.getOneById(id);
                isTable = formDialog.getIstable();
                dsName = formDialog.getDsalias();
                objectName = formDialog.getObjname();
                map.put("bpmFormDialog", formDialog);
            }
        }
        try {
            TableModel tableModel;
            String dbType = dataSourceType.toLowerCase();
            // 表
            if (isTable == FormConstants.DEFAULT_INT_ONE) {
                BaseTableMeta meta = TableMetaFactory.getMetaData(dsName, dbType);
                tableModel = meta.getTableByName(objectName);
            }
            // 视图处理
            else {
                IDbView dbView = TableMetaFactory.getDbView(dsName, dbType);
                tableModel = dbView.getModelByViewName(objectName);
            }
            map.put("tableModel", tableModel);
            DbContextHolder.clearDataSource();
            DbContextHolder.setDefaultDataSourceMy(dataSourceType);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("query.success", map);
        } catch (Exception ex) {
            ex.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
    }

    /**
     * 添加或更新通用表单查询。
     *
     * @param bpmFormQuery FormQuery
     * @return ResultData
     */
    @RequestMapping(UrlConstants.MODULE_FUNCTION_ADD_UPDATE)
    @ResponseBody
    @Action(description = "添加或更新通用表单查询", exectype = "添加或更新日志",
            detail = "<#if isAdd==0>添加<#else>更新</#if>" +
                    "通用表单查询【${name}】<#if success>成功<#else>失败</#if>")
    public ResultData save(@RequestBody FormQuery bpmFormQuery) {
        //自定义查询添加
        if (StringUtil.isEmpty(bpmFormQuery.getId())) {
            bpmFormQuery.setId(UUIDUtils.getUUIDFor32());
            String alias = bpmFormQuery.getAlias();
            boolean isExist = formQueryService.isExistAlias(alias);
            if (isExist) {
                return getResultDataError("formQuery.alias.warn");
            }
            bpmFormQuery.setConditionfield(StringEscapeUtils.unescapeHtml4(bpmFormQuery.getConditionfield()));
            bpmFormQuery.setResultfield(StringEscapeUtils.unescapeHtml4(bpmFormQuery.getResultfield()));
            bpmFormQuery.setSortfield(StringEscapeUtils.unescapeHtml4(bpmFormQuery.getSortfield()));
            formQueryService.add(bpmFormQuery);
            SysAuditThreadLocalHolder.putParamerter("isAdd", 0 );
            SysAuditThreadLocalHolder.putParamerter("name", bpmFormQuery.getName());
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("formQuery.add.success");
        } else {
            //自定义查询修改
            String alias = bpmFormQuery.getAlias();
            boolean isExist = formQueryService.isExistAliasForUpd(bpmFormQuery.getId(), alias);
            if (isExist) {
                return getResultDataError("formQuery.alias.warn");
            }
            formQueryService.updatePart(bpmFormQuery);
            SysAuditThreadLocalHolder.putParamerter("isAdd", 1 );
            SysAuditThreadLocalHolder.putParamerter("name", bpmFormQuery.getName());
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("formQuery.update.success");
        }
    }

    /**
     * 根据别名查询自定义查询
     * @param request HttpServletRequest
     * @return ResultData
     */
    @RequestMapping("/queryObj")
    @ResponseBody
    @Action(description = "根据别名查询自定义查询", exectype = "查询日志",
            detail = "查看自定义查询<#if success>成功<#else>失败</#if>")
    public ResultData queryObj(HttpServletRequest request){
        String alias = RequestUtil.getString(request, "alias");
        FormQuery formQuery = formQueryService.getByAlias(alias);
        formQuery.setConditionfield(StringEscapeUtils.unescapeHtml4(formQuery.getConditionfield()));
        formQuery.setResultfield(StringEscapeUtils.unescapeHtml4(formQuery.getResultfield()));
        formQuery.setSortfield(StringEscapeUtils.unescapeHtml4(formQuery.getSortfield()));
        SysAuditThreadLocalHolder.putParamerter("success", true);
        return getResultDataSuccess("query.success", formQuery);
    }

    /**
     * 进行查询
     *
     * @param request HttpServletRequest
     * @return ResultData
     */
    @RequestMapping("/doQuery")
    @ResponseBody
    @Action(description = "自定义查询预览中进行查询", exectype = "查询日志",
            detail = "根据自定义查询查询数据<#if success>成功<#else>失败</#if>")
    public ResultData doQuery(HttpServletRequest request){
        String alias = RequestUtil.getString(request, "alias");
        String queryData = StringEscapeUtils.unescapeHtml4(RequestUtil.getString(request, "querydata"));
        Integer page = RequestUtil.getInt(request, "page", 0);
        Integer pageSize = RequestUtil.getInt(request, "pagesize", 0);
        FormQuery bpmFormQuery = formQueryService.getByAlias(alias);
        bpmFormQuery.setConditionfield(StringEscapeUtils.unescapeHtml4(bpmFormQuery.getConditionfield()));
        bpmFormQuery.setResultfield(StringEscapeUtils.unescapeHtml4(bpmFormQuery.getResultfield()));
        bpmFormQuery.setSortfield(StringEscapeUtils.unescapeHtml4(bpmFormQuery.getSortfield()));
        QueryResult result;
        try {
            result = formQueryService.getData(bpmFormQuery, queryData, page, pageSize);
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
        DbContextHolder.clearDataSource();
        DbContextHolder.setDefaultDataSourceMy(dataSourceType);
        SysAuditThreadLocalHolder.putParamerter("success", true);
        return getResultDataSuccess("query.success", result);
    }

    /**
     * 选择自定义查询（取得所有自定义查询）
     *
     * @return 自定义查询列表
     */
    @RequestMapping("/getAllQueries")
    @Action(description = "查询自定义查询数据列表", exectype = "查询日志",
            detail = "查询自定义查询数据列表<#if success>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData getAllQueries() {
        try {
            List<FormQuery> list = formQueryService.getAllQueries();
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("query.success", list);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
    }
}
